import { isObject, isString } from '/@/utils/is';

const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss';

// 函数重载签名,重载签名的目的是为了提供类型推断支持，根据传入的参数得到更精确的返回类型。它在实际代码中不会被调用。
export function joinTimestamp<T extends boolean>(
  join: boolean,
  restful: T,
): T extends true ? string : object;

/**
 * 根据给定的参数生成时间戳相关的字符串或对象。
 * @param join - 是否生成时间戳。为 true 时生成，为 false 时返回空字符串或空对象。
 * @param restful - 是否生成 RESTful 风格的时间戳字符串。默认为 false。
 * @returns 如果 join 为 false，则根据 restful 参数返回空字符串或空对象。
 *          如果 join 为 true，则根据 restful 参数返回带时间戳的字符串或包含时间戳属性的对象。
 */
export function joinTimestamp(join: boolean, restful = false): string | object {
  if (!join) {
    return restful ? '' : {};
  }
  const now = new Date().getTime();
  if (restful) {
    return `?_t=${now}`;
  }
  return { _t: now };
}

/**
 * 对请求参数对象进行处理，包括格式化日期、去除字符串的首尾空格等操作。
 *
 * @param {Recordable} params - 待处理的参数对象
 * @returns {void}
 * @example 
    const params = {
      date: dayjs(),
      name: 'John Doe',
      address: {
        street: '123 Main St',
        city: 'New York',
        state: 'NY'
      }
    };
    formatRequestDate(params);
    这里的日期不能用new Date()获取，而必须用dayjs，只有dayjs才有format属性
 */
export function formatRequestDate(params: Recordable) {
  //检查传入的 params 参数是否为对象类型，如果不是则直接返回
  if (Object.prototype.toString.call(params) !== '[object Object]') {
    return;
  }

  for (const key in params) {
    //判断params[key]对应的对象中是否有format属性，它应该是个函数
    const format = params[key]?.format ?? null;
    //format属性是否是个函数
    if (format && typeof format === 'function') {
      //用格式DATE_TIME_FORMAT对params[key]进行日期格式化
      params[key] = params[key].format(DATE_TIME_FORMAT);
    }

    //对于属性名为字符串类型的属性，函数还会检查其属性值 value 是否存在，并且尝试对其进行去除首尾空格的操作。
    if (isString(key)) {
      const value = params[key];
      if (value) {
        try {
          params[key] = isString(value) ? value.trim() : value;
        } catch (error: any) {
          throw new Error(error);
        }
      }
    }
    //如果 params[key] 是一个对象，函数还会递归调用自身
    if (isObject(params[key])) {
      formatRequestDate(params[key]);
    }
  }
}
